﻿using System.Collections.Generic;
using System.Linq;
using System.Data;
using System.Data.Objects;

namespace Fujitsu.JiraAnalysis.DAL
{
    public interface IIssuesTypeStorage
    {
        List<IssueTypeMapping> GetIssueTypesMappingOfProject(int projectId);
    }

    public class IssuesTypeStorage : IIssuesTypeStorage
    {
        public List<IssueTypeMapping> GetIssueTypesMappingOfProject(int projectId)
        {
            using (var entityModel = new JiraAnalysisDBEntities())
            {
                return (from t in entityModel.IssueTypeMapping.Include("IssueType")
                        where t.ProjectID == projectId
                        select t).ToList();
            }
        }
        public List<IssueType> GetIssueTypes()
        {
            using (var db = new JiraAnalysisDBEntities())
            {
                return db.IssueType.ToList();
            }
        }

        public void UpdateMapping(int projectId, int jiraTypeId, int dbTypeId, string jiraTypeName)
        {
            using (var db = new JiraAnalysisDBEntities())
            {
                var typeMapping = (from type in db.IssueTypeMapping
                                   where type.ProjectID == projectId
                                   && type.JiraTypeID == jiraTypeId
                                   && type.Name == jiraTypeName
                                   select type).FirstOrDefault();

                var isToAddTypeMapping = false;

                if (typeMapping != null)
                {
                    if (typeMapping.TypeID != dbTypeId)
                    {
                        db.IssueTypeMapping.DeleteObject(typeMapping);
                        isToAddTypeMapping = true;
                    }
                }
                else
                {
                    isToAddTypeMapping = true;
                }

                if (isToAddTypeMapping)
                {
                    var priorityNewMapping = new IssueTypeMapping
                    {
                        ProjectID = projectId,
                        JiraTypeID = jiraTypeId,
                        TypeID = dbTypeId,
                        Name = jiraTypeName
                    };
                    try
                    {
                        db.IssueTypeMapping.AddObject(priorityNewMapping);
                        db.SaveChanges();
                    }
                    catch (OptimisticConcurrencyException)
                    {
                        db.Refresh(RefreshMode.ClientWins, priorityNewMapping);
                        db.SaveChanges();
                    }
                    catch (DataException)
                    {
                    }
                }
            }
        }

        public int GetIssueTypeMapping(int projectId, int jiraTypeId)
        {
            using (var db = new JiraAnalysisDBEntities())
            {
                var typeMapping = db.IssueTypeMapping.Where(r => r.ProjectID == projectId && r.JiraTypeID == jiraTypeId).FirstOrDefault();
                if (typeMapping != null)
                    return typeMapping.TypeID;
                return -1;
            }
        }

        public void UpdateResolutionName(int projectId, int jiraIssueTypeId, string issueTypeName)
        {
            using (var db = new JiraAnalysisDBEntities())
            {
                var issueTypeMap = db.IssueTypeMapping.Where(
                        s => s.ProjectID == projectId && s.JiraTypeID == jiraIssueTypeId).
                        FirstOrDefault();
                if (issueTypeMap == null)
                    return;
                issueTypeMap.Name = issueTypeName;
                try
                {
                    db.SaveChanges();
                }
                catch (OptimisticConcurrencyException)
                {
                    db.Refresh(RefreshMode.ClientWins, issueTypeMap);
                    db.SaveChanges();
                }
                catch (DataException)
                {
                }
            }
        }

        public List<IssueTypeMapping> GetIssueTypeMappings(int projcetId)
        {
            using (var db = new JiraAnalysisDBEntities())
            {
                return db.IssueTypeMapping.Where(i => i.ProjectID == projcetId).ToList();
                try
                {
                    return db.IssueTypeMapping.Where(i => i.ProjectID == projcetId).ToList();
                }
                catch (EntityException ex)
                {
                    return new List<IssueTypeMapping>();
                }
            }
        }

        public void DeleteIssueTypeMapping(int projectId, int jiratypeId, int typeId)
        {
            using (var db = new JiraAnalysisDBEntities())
            {
                var dbIssueTypeMapping = db.IssueTypeMapping.FirstOrDefault(i => i.ProjectID == projectId && i.JiraTypeID == jiratypeId && i.TypeID == typeId);
                if (dbIssueTypeMapping == null)
                    return;

                try
                {
                    db.IssueTypeMapping.DeleteObject(dbIssueTypeMapping);
                    db.SaveChanges();
                }
                catch (OptimisticConcurrencyException)
                {
                    db.Refresh(RefreshMode.ClientWins, dbIssueTypeMapping);
                    db.SaveChanges();
                }
                catch (DataException ex)
                {
                    //EventLogger.CreateInstance(eventLog).LogWriteError(string.Concat("Can't delete issue from DB.", Environment.NewLine, ex.StackTrace));
                }
            }
        }

        public void DeleteIssueTypeMappingOfProject(int projcetId)
        {
            var issueTypeMappings = GetIssueTypeMappings(projcetId);
            foreach (var issueTypeMapping in issueTypeMappings)
            {
                DeleteIssueTypeMapping(issueTypeMapping.ProjectID, issueTypeMapping.JiraTypeID, issueTypeMapping.TypeID);
            }
        }
    }
}
